using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Schema;
using xml2db.DatabaseStructure;

namespace xml2db
{
	public class XmlSchemaParser: ISchemaParser, ISchemaVisitor
	{
		private class XmlSchemaContext
		{
			private INode schemaNode;
			private bool isOptional;

			public XmlSchemaContext(INode node, bool optional)
			{
				schemaNode = node;
				isOptional = optional;
			}

			public INode SchemaNode
			{
				get
				{
					return schemaNode;
				}

				set
				{
					schemaNode = value;
				}
			}

			public bool Optional
			{
				get
				{
					return isOptional;
				}

				set
				{
					isOptional = value;
				}
			}
		}
		private IProvider databaseProvider;
		private Dictionary<string, ITable> tableDictionary;

		public XmlSchemaParser()
		{
			tableDictionary = new Dictionary<string, ITable>();
		}

		public ICollection<ITable> Parse(XmlSchemaSet schema, IProvider provider)
		{
			tableDictionary.Clear();
			databaseProvider = provider;

			foreach (XmlSchema xmlSchema in schema.Schemas())
			{
				Visit(xmlSchema, null);
			}

			return tableDictionary.Values;
		}
		
		public void Visit(XmlSchema node, Object context)
		{
			foreach (XmlSchemaElement element in node.Elements.Values)
			{
				Visit(element, context);
			}			
		}

		public void Visit(XmlSchemaElement node, Object context)
		{
			if (node.ElementSchemaType is XmlSchemaSimpleType)
			{
				ReadSimpleSchemaNode(node, null); 
			}
			else if (node.ElementSchemaType is XmlSchemaComplexType)
			{
				ReadComplexSchemaNode(node, null);
			}
		}

		public void Visit(XmlSchemaGroupRef node, Object context)
		{ 
		}

		public void Visit(XmlSchemaChoice node, Object context)
		{ 
		}

		public void Visit(XmlSchemaSequence node, Object context)
		{ 
		}

		void ReadSimpleSchemaNode(XmlSchemaElement node, Object context)
		{
			XmlSchemaSimpleType nodeType = node.ElementSchemaType as XmlSchemaSimpleType;
			bool nullable = (node.MinOccurs > 0 ? false : true);
			bool isCollectionField = (node.MaxOccurs > 1 ? true : false);

			string name = node.Name;
			string typeName = nodeType.Name;
			bool isSpecialDomainType = false;
			XmlSchemaDerivationMethod deriveMethod = nodeType.DerivedBy;
			if (string.IsNullOrEmpty(typeName) &&
				deriveMethod == XmlSchemaDerivationMethod.Restriction &&
				nodeType.BaseXmlSchemaType != null &&
				nodeType.BaseXmlSchemaType.DerivedBy == XmlSchemaDerivationMethod.Restriction &&
				!string.IsNullOrEmpty(nodeType.BaseXmlSchemaType.Name))
			{
				isSpecialDomainType = true;
			}

			if (context != null)
			{
				XmlSchemaContext schemaContext = context as XmlSchemaContext;
				ITable parentTable = schemaContext.SchemaNode as ITable;

			}

		}

		void ReadComplexSchemaNode(XmlSchemaElement node, Object context)
		{
 
		}
	}
}
